<template>
    <div>
        <div>
            <el-form class="form" :inline="true">
                <el-form-item>
                    <el-radio-group v-model="convert.uploadStyle" size="large">
                        <el-radio-button :label="false">手动选择</el-radio-button>
                        <el-radio-button :label="true">拖拽选择</el-radio-button>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="输出格式">
                    <el-select class="form-select" v-model="convert.config.outputFormat">
                        <el-option v-for="item in convert.outputFormats" :key="item.label" :label="item.label" :value="item.label"/>
                    </el-select>
                </el-form-item>
                <el-form-item label="无损压缩" v-if="convert.config.outputFormat=='webp'">
                    <!-- 编码器选项 -->
                    <el-switch v-model="convert.config.webpLossless" />
                </el-form-item>
                <el-form-item label="质量参数" v-if="convert.config.outputFormat=='jpg' || (convert.config.outputFormat=='webp'&&!convert.config.webpLossless)">
                    <el-input-number :min="1" :max="100" v-model="convert.config.quality" />
                </el-form-item>
                <el-form-item label="保留透明色块RGB值" v-if="convert.config.outputFormat=='webp'">
                    <!-- 编码器选项 -->
                    <el-switch v-model="convert.config.webpExact" />
                </el-form-item>
                <el-form-item label="最大色块数量" v-if="convert.config.outputFormat=='gif'">
                    <el-input-number :min="1" :max="256" v-model="convert.config.gifMaxColorNum"/>
                </el-form-item>
            </el-form>
        </div>

        <div>
            <div class="upload-1" v-if="!convert.uploadStyle">
                <el-upload
                action=""
                ref="upload1"
                list-type="picture-card"
                :http-request="customSubmit"
                :auto-upload="false"
                :on-change="limitHandle1"
                :on-preview="dialog.ImagePreview"
                multiple>
                    <el-icon v-show="!isDisable"><Plus /></el-icon>
                    <el-icon v-show="isDisable"><Loading /></el-icon>
                </el-upload>
                <el-dialog class="dialog" :show-close="false" v-model="dialog.visable">
                    <el-image style="width: 100%;" :src="dialog.url" alt="Preview Image" />
                </el-dialog>

                <el-button class="upload-1-btn" size="large" :loading="isDisable" @click="submit()" round>
                    <el-icon size="22"><Cpu /></el-icon>
                    开始转换
                </el-button>
                <div>
                    <span class="el-upload__tip">支持输入png/webp/jpg/gif文件，且小于20MB</span>
                </div>
            </div>

            <div v-else>
                <el-upload
                class="upload-2"
                action=""
                :before-upload="limitHandle2"
                :show-file-list="false"
                :http-request="customSubmit"
                drag
                multiple>
                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                    <div class="el-upload__text">
                        拖拽文件或<em>点击上传</em>
                    </div>
                    <template #tip>
                        <span class="el-upload__tip">支持输入png/webp/jpg/gif文件，且小于20MB</span>
                    </template>
                </el-upload>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import {ref,onMounted} from "vue"
import {type UploadFile,type UploadInstance,type UploadRequestOptions,type UploadRawFile} from "element-plus"
import { UploadFilled,Plus,Cpu,Loading } from '@element-plus/icons-vue'
import useConvert from "@/hooks/convert/convert"
import {type ReqWEBP,ReqConvertWebpUrl} from "@/types/types"
import axios from "axios"
let {initConvert}=useConvert()
let convert=initConvert()
onMounted(()=>{
    convert.onMountedFunc()
})

let upload1=ref<UploadInstance>()

let {initDialog}=useConvert()
let dialog=initDialog()
//自定义上传
function customSubmit(option: UploadRequestOptions){
    switch(convert.config.outputFormat){
        case "webp":
            ToWebpHandle(option.file)
            break
        default:
            defaultHandle(option.file)
    }
}

async function defaultHandle(file:UploadRawFile){
    let output=new Uint8Array()
    let bytes=new Uint8Array()
    let reader = new FileReader();
    reader.readAsArrayBuffer(file)
    reader.onload = ()=>{
        //读取字节数据
        bytes=new Uint8Array(<ArrayBuffer>reader.result)
        switch(convert.config.outputFormat){
        case "png":
            output=convert.wasmFunc.toPNG(bytes,file.name)
            break
        case "jpg":
            output=convert.wasmFunc.toJPEG(bytes,file.name,convert.config.quality)
            break
        case "gif":
            output=convert.wasmFunc.toGIF(bytes,file.name,convert.config.gifMaxColorNum)
            break
        }
        let outputFileName = convert.getOutputFileName(file.name)
        let outputFile = new File([output], outputFileName);
        let outputUrl=URL.createObjectURL(outputFile)
        convert.downloadFile(outputFileName,outputUrl)
        URL.revokeObjectURL(outputUrl)
    }
}

async function ToWebpHandle(file:UploadRawFile)
{
    let output=new Uint8Array()
    let formData = new FormData()
    formData.append("image", file)
    let params:ReqWEBP={
        lossless:convert.config.webpLossless,
	    quality:convert.config.quality,
	    exact:convert.config.webpExact
    }
    formData.set("lossless",String(params.lossless))
    formData.set("quality",String(params.quality))
    formData.set("exact",String(params.exact))
    axios.post<Uint8Array>(ReqConvertWebpUrl,formData,{
        responseType: 'blob',
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    }).then((res)=>{
        //获取数据
        output=res.data
        let outputFileName = convert.getOutputFileName(file.name)
        let outputFile = new File([output], outputFileName);
        let outputUrl=URL.createObjectURL(outputFile)
        convert.downloadFile(outputFileName,outputUrl)
        URL.revokeObjectURL(outputUrl)
    }).catch((err)=>{
        console.log(err)
    })
}
//upload2
let isDisable=ref(false)
function submit(){
    isDisable.value=true
    upload1.value?.submit()
    setTimeout(()=>{
        isDisable.value=false
    },1000)
}
//limit
function limitHandle1(file:UploadFile){
    if(!convert.limit(file.raw?.type||"",file.raw?.size||-1)){
        upload1.value?.handleRemove(file)
    }
}
function limitHandle2(file:UploadRawFile):boolean{
    return convert.limit(file.type||"",file.size||-1)
}
</script>

<style scoped>
.form{
    margin-top: 1rem;
}
.form-select{
    width: 10rem;
}
.upload-1{
    margin-bottom: 1rem;
    border: 0.1rem dashed 	#87CEFA;
    border-radius: 1rem;
    width: 92.4%;
    min-width: 39rem;
    padding: 1rem;
    padding-right: 0;
}
.upload-1-btn{
    margin-top: 0.5rem;
}
.upload-2{
    margin-bottom: 1rem;
}
</style>
<style lang="scss" scoped>
:deep(.el-dialog__header) {
  padding: 0;
}
:deep(.el-dialog__body) {
  padding: 0;
  height: 0;
}
</style>